import { loadBase64, imageToSprite } from '../util.js';
import MapleStoryGlobal from '../global.js';

export class Background {
    constructor(resource, stage) {
        this.resource = resource;
        this.stage = stage;
        // 保存所有,Obj的Container
        this.backArr = [];
        this.updateArr = [];
    }

    async load(Map) {
        const resource = this.resource;

        if (!Map.back) {
            return;
        }

        const VWIDTH = MapleStoryGlobal.app.view.width;
        const VHEIGHT = MapleStoryGlobal.app.view.height;
        const WOFFSET = VWIDTH / 2;
        const HOFFSET = VHEIGHT / 2;

        const Type =
        {
            NORMAL: 0, //
            HTILED: 1, //
            VTILED: 2,
            TILED: 3, //
            HMOVEA: 4,
            VMOVEA: 5,
            HMOVEB: 6,
            VMOVEB: 7,
        };

        for (let item of Object.values(Map.back)) {
            let { bS, x, y, no, cx, cy, type, rx, ry } = item;
            let htile = 0;
            let vtile = 0;
            let hspeed = 0;
            let vspeed = 0;
            x = Number(x);
            y = Number(y);
            cx = Number(cx);
            cy = Number(cy);
            rx = Number(rx);
            ry = Number(ry);
            type = Number(type);
            // if (bS) {
            //     await resource.load('Map/Back', `./Map/Back/${bS}.img.json`);
            // }
            const Back = resource.Content.Map.Back;
            let back = Back[`${bS}`] && Back[`${bS}`].back[no];
            if (!back) {
                return;
            }
            const image = await loadBase64(back.value)
            // TODO: Double check for zero. Is this a WZ reading issue?
            if (cx == 0)
                cx = (image.width > 0) ? image.width : 1;

            if (cy == 0)
                cy = (image.height > 0) ? image.height : 1;

            htile = 1;
            vtile = 1;



            switch (type) {
                case Type.HTILED:
                case Type.HMOVEA:
                    htile = VWIDTH / cx + 3;
                    break;
                case Type.VTILED:
                case Type.VMOVEA:
                    vtile = VHEIGHT / cy + 3;
                    break;
                case Type.TILED:
                case Type.HMOVEB:
                case Type.VMOVEB:
                    htile = VWIDTH / cx + 3;
                    vtile = VHEIGHT / cy + 3;
                    break;
            }
            switch (type) {
                case Type.HMOVEA:
                case Type.HMOVEB:
                    hspeed = rx / 16;
                    break;
                case Type.VMOVEA:
                case Type.VMOVEB:
                    vspeed = ry / 16;
                    break;
            }
            x += rx * (WOFFSET) / 100 + WOFFSET
            y += ry * (HOFFSET) / 100 + HOFFSET
            if (htile > 1) {
                while (x > 0)
                    x -= cx;

                while (x < -cx)
                    x += cx;
            }

            if (vtile > 1) {
                while (y > 0)
                    y -= cy;

                while (y < -cy)
                    y += cy;
            }
            const tw = cx * htile;
            const th = cy * vtile;

            for (let tx = 0; tx < tw; tx += cx) {
                for (let ty = 0; ty < th; ty += cy) {
                    let animation = imageToSprite(image);
                    animation.x = x + tx - back.origin.x;
                    animation.y = y + ty - back.origin.y;
                    this.backArr.push(animation)
                    if (hspeed || vspeed) {
                        this.updateArr.push(() => {
                            if (hspeed) {
                                if (hspeed > 0 && animation.x >= VWIDTH) {
                                    animation.x = -animation.width;
                                } else if (hspeed < 0 && animation.x <= -animation.width) {
                                    animation.x = VWIDTH;
                                }
                                animation.x += hspeed;
                            } 
                            if (vspeed) {
                                if (vspeed > 0 && animation.y >= y + ty - back.origin.y + VHEIGHT) {
                                    animation.y = y + ty - back.origin.y - VHEIGHT
                                } else if (vspeed < 0 && animation.y <= y + ty - back.origin.y - VHEIGHT) {
                                    animation.y = y + ty - back.origin.y + VHEIGHT
                                }
                                animation.y += vspeed;
                            }
                        })
                    }
                }
            }

        }
    }

    update() {
        this.updateArr.forEach(u => u())
    }

    draw() {
        const stage = this.stage;
        const backArr = this.backArr;

        backArr.forEach(sprite => {
            stage.addChild(sprite);
        })
    }

    destroy() {
        const stage = this.stage;
        const backArr = this.backArr;
        const updateArr = this.updateArr;

        backArr.forEach(b => {
            stage.removeChild(b);
        })
        backArr.length = 0;
        updateArr.length = 0;
    }

}